home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 401-425 / disk_407 / flex / src.lzh / src / scan.l < prev    next >
Text File  |  1990-07-14  |  12KB  |  534 lines

  1.  
  2. /* scan.l - scanner for flex input */
  3.  
  4. %{
  5. /*-
  6.  * Copyright (c) 1990 The Regents of the University of California.
  7.  * All rights reserved.
  8.  *
  9.  * This code is derived from software contributed to Berkeley by
  10.  * Vern Paxson.
  11.  * 
  12.  * The United States Government has rights in this work pursuant
  13.  * to contract no. DE-AC03-76SF00098 between the United States
  14.  * Department of Energy and the University of California.
  15.  *
  16.  * Redistribution and use in source and binary forms are permitted provided
  17.  * that: (1) source distributions retain this entire copyright notice and
  18.  * comment, and (2) distributions including binaries display the following
  19.  * acknowledgement:  ``This product includes software developed by the
  20.  * University of California, Berkeley and its contributors'' in the
  21.  * documentation or other materials provided with the distribution and in
  22.  * all advertising materials mentioning features or use of this software.
  23.  * Neither the name of the University nor the names of its contributors may
  24.  * be used to endorse or promote products derived from this software without
  25.  * specific prior written permission.
  26.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  27.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  28.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  29.  */
  30.  
  31. #ifndef lint
  32. static char rcsid[] =
  33.     "@(#) $Header: WPL:Generators/flex-2.3/RCS/scan.l,v 1.2 90/07/15 01:16:31 loftus Exp $ (LBL)";
  34. #endif
  35.  
  36. #undef yywrap
  37.  
  38. #include "flexdef.h"
  39. #include "parse.h"
  40.  
  41. #define ACTION_ECHO fprintf( temp_action_file, "%s", yytext )
  42. #define MARK_END_OF_PROLOG fprintf( temp_action_file, "%%%% end of prolog\n" );
  43.  
  44. #undef YY_DECL
  45. #define YY_DECL \
  46.     int flexscan()
  47.  
  48. #define RETURNCHAR \
  49.     yylval = yytext[0]; \
  50.     return ( CHAR );
  51.  
  52. #define RETURNNAME \
  53.     (void) strcpy( nmstr, (char *) yytext ); \
  54.     return ( NAME );
  55.  
  56. #define PUT_BACK_STRING(str, start) \
  57.     for ( i = strlen( (char *) (str) ) - 1; i >= start; --i ) \
  58.         unput((str)[i])
  59.  
  60. #define CHECK_REJECT(str) \
  61.     if ( all_upper( str ) ) \
  62.         reject = true;
  63.  
  64. #define CHECK_YYMORE(str) \
  65.     if ( all_lower( str ) ) \
  66.         yymore_used = true;
  67. %}
  68.  
  69. %x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE
  70. %x FIRSTCCL CCL ACTION RECOVER BRACEERROR C_COMMENT ACTION_COMMENT
  71. %x ACTION_STRING PERCENT_BRACE_ACTION USED_LIST CODEBLOCK_2 XLATION
  72.  
  73. WS        [ \t\f]+
  74. OPTWS        [ \t\f]*
  75. NOT_WS        [^ \t\f\n]
  76.  
  77. NAME        [a-z_][a-z_0-9-]*
  78. NOT_NAME    [^a-z_\n]+
  79.  
  80. SCNAME        {NAME}
  81.  
  82. ESCSEQ        \\([^\n]|[0-9]{1,3}|x[0-9a-f]{1,2})
  83.  
  84. %%
  85.     static int bracelevel, didadef;
  86.     int i, indented_code, checking_used, new_xlation;
  87.     int doing_codeblock = false;
  88.     Char nmdef[MAXLINE], myesc();
  89.  
  90. ^{WS}            indented_code = true; BEGIN(CODEBLOCK);
  91. ^#.*\n            ++linenum; /* treat as a comment */
  92. ^"/*"            ECHO; BEGIN(C_COMMENT);
  93. ^"%s"{NAME}?        return ( SCDECL );
  94. ^"%x"{NAME}?        return ( XSCDECL );
  95. ^"%{".*\n        {
  96.             ++linenum;
  97.             line_directive_out( stdout );
  98.             indented_code = false;
  99.             BEGIN(CODEBLOCK);
  100.             }
  101.  
  102. {WS}            return ( WHITESPACE );
  103.  
  104. ^"%%".*            {
  105.             sectnum = 2;
  106.             line_directive_out( stdout );
  107.             BEGIN(SECT2PROLOG);
  108.             return ( SECTEND );
  109.             }
  110.  
  111. ^"%used"        {
  112.     pinpoint_message( "warning - %%used/%%unused have been deprecated" );
  113.             checking_used = REALLY_USED; BEGIN(USED_LIST);
  114.             }
  115. ^"%unused"        {
  116.             checking_used = REALLY_NOT_USED; BEGIN(USED_LIST);
  117.     pinpoint_message( "warning - %%used/%%unused have been deprecated" );
  118.             checking_used = REALLY_NOT_USED; BEGIN(USED_LIST);
  119.             }
  120.  
  121.  
  122. ^"%"[aeknopt]" ".*\n    {
  123. #ifdef NOTDEF
  124.             fprintf( stderr,
  125.                  "old-style lex command at line %d ignored:\n\t%s",
  126.                  linenum, yytext );
  127. #endif
  128.             ++linenum;
  129.             }
  130.  
  131. ^"%"[cr]{OPTWS}        /* ignore old lex directive */
  132.  
  133. %t{OPTWS}\n        {
  134.             ++linenum;
  135.             xlation =
  136.                 (int *) malloc( sizeof( int ) * (unsigned) csize );
  137.  
  138.             if ( ! xlation )
  139.                 flexfatal(
  140.                 "dynamic memory failure building %t table" );
  141.  
  142.             for ( i = 0; i < csize; ++i )
  143.                 xlation[i] = 0;
  144.  
  145.             num_xlations = 0;
  146.  
  147.             BEGIN(XLATION);
  148.             }
  149.  
  150. ^"%"[^sxanpekotcru{}]{OPTWS}    synerr( "unrecognized '%' directive" );
  151.  
  152. ^{NAME}            {
  153.             (void) strcpy( nmstr, (char *) yytext );
  154.             didadef = false;
  155.             BEGIN(PICKUPDEF);
  156.             }
  157.  
  158. {SCNAME}        RETURNNAME;
  159. ^{OPTWS}\n        ++linenum; /* allows blank lines in section 1 */
  160. {OPTWS}\n        ++linenum; return ( '\n' );
  161. .            synerr( "illegal character" ); BEGIN(RECOVER);
  162.  
  163.  
  164. <C_COMMENT>"*/"        ECHO; BEGIN(INITIAL);
  165. <C_COMMENT>"*/".*\n    ++linenum; ECHO; BEGIN(INITIAL);
  166. <C_COMMENT>[^*\n]+    ECHO;
  167. <C_COMMENT>"*"        ECHO;
  168. <C_COMMENT>\n        ++linenum; ECHO;
  169.  
  170.  
  171. <CODEBLOCK>^"%}".*\n    ++linenum; BEGIN(INITIAL);
  172. <CODEBLOCK>"reject"    ECHO; CHECK_REJECT(yytext);
  173. <CODEBLOCK>"yymore"    ECHO; CHECK_YYMORE(yytext);
  174. <CODEBLOCK>{NAME}|{NOT_NAME}|.    ECHO;
  175. <CODEBLOCK>\n        {
  176.             ++linenum;
  177.             ECHO;
  178.             if ( indented_code )
  179.                 BEGIN(INITIAL);
  180.             }
  181.  
  182.  
  183. <PICKUPDEF>{WS}        /* separates name and definition */
  184.  
  185. <PICKUPDEF>{NOT_WS}.*    {
  186.             (void) strcpy( (char *) nmdef, (char *) yytext );
  187.  
  188.             for ( i = strlen( (char *) nmdef ) - 1;
  189.                   i >= 0 &&
  190.                   nmdef[i] == ' ' || nmdef[i] == '\t';
  191.                   --i )
  192.                 ;
  193.  
  194.             nmdef[i + 1] = '\0';
  195.  
  196.                         ndinstal( nmstr, nmdef );
  197.             didadef = true;
  198.             }
  199.  
  200. <PICKUPDEF>\n        {
  201.             if ( ! didadef )
  202.                 synerr( "incomplete name definition" );
  203.             BEGIN(INITIAL);
  204.             ++linenum;
  205.             }
  206.  
  207. <RECOVER>.*\n        ++linenum; BEGIN(INITIAL); RETURNNAME;
  208.  
  209.  
  210. <USED_LIST>\n        ++linenum; BEGIN(INITIAL);
  211. <USED_LIST>{WS}
  212. <USED_LIST>"reject"    {
  213.             if ( all_upper( yytext ) )
  214.                 reject_really_used = checking_used;
  215.             else
  216.                 synerr( "unrecognized %used/%unused construct" );
  217.             }
  218. <USED_LIST>"yymore"    {
  219.             if ( all_lower( yytext ) )
  220.                 yymore_really_used = checking_used;
  221.             else
  222.                 synerr( "unrecognized %used/%unused construct" );
  223.             }
  224. <USED_LIST>{NOT_WS}+    synerr( "unrecognized %used/%unused construct" );
  225.  
  226.  
  227. <XLATION>"%t"{OPTWS}\n    ++linenum; BEGIN(INITIAL);
  228. <XLATION>^{OPTWS}[0-9]+    ++num_xlations; new_xlation = true;
  229. <XLATION>^.        synerr( "bad row in translation table" );
  230. <XLATION>{WS}        /* ignore whitespace */
  231.  
  232. <XLATION>{ESCSEQ}    {
  233.             xlation[myesc( yytext )] =
  234.                 (new_xlation ? num_xlations : -num_xlations);
  235.             new_xlation = false;
  236.             }
  237. <XLATION>.        {
  238.             xlation[yytext[0]] =
  239.                 (new_xlation ? num_xlations : -num_xlations);
  240.             new_xlation = false;
  241.             }
  242.  
  243. <XLATION>\n        ++linenum;
  244.  
  245.  
  246. <SECT2PROLOG>.*\n/{NOT_WS}    {
  247.             ++linenum;
  248.             ACTION_ECHO;
  249.             MARK_END_OF_PROLOG;
  250.             BEGIN(SECT2);
  251.             }
  252.  
  253. <SECT2PROLOG>.*\n    ++linenum; ACTION_ECHO;
  254.  
  255. <SECT2PROLOG><<EOF>>    MARK_END_OF_PROLOG; yyterminate();
  256.  
  257. <SECT2>^{OPTWS}\n    ++linenum; /* allow blank lines in section 2 */
  258.  
  259. <SECT2>^({WS}|"%{")    {
  260.             indented_code = (yytext[0] != '%');
  261.             doing_codeblock = true;
  262.             bracelevel = 1;
  263.  
  264.             if ( indented_code )
  265.                 ACTION_ECHO;
  266.  
  267.             BEGIN(CODEBLOCK_2);
  268.             }
  269.  
  270. <SECT2>"<"        BEGIN(SC); return ( '<' );
  271. <SECT2>^"^"        return ( '^' );
  272. <SECT2>\"        BEGIN(QUOTE); return ( '"' );
  273. <SECT2>"{"/[0-9]        BEGIN(NUM); return ( '{' );
  274. <SECT2>"{"[^0-9\n][^}\n]*    BEGIN(BRACEERROR);
  275. <SECT2>"$"/[ \t\n]    return ( '$' );
  276.  
  277. <SECT2>{WS}"%{"        {
  278.             bracelevel = 1;
  279.             BEGIN(PERCENT_BRACE_ACTION);
  280.             return ( '\n' );
  281.             }
  282. <SECT2>{WS}"|".*\n    continued_action = true; ++linenum; return ( '\n' );
  283.  
  284. <SECT2>{WS}        {
  285.             /* this rule is separate from the one below because
  286.              * otherwise we get variable trailing context, so
  287.              * we can't build the scanner using -{f,F}
  288.              */
  289.             bracelevel = 0;
  290.             continued_action = false;
  291.             BEGIN(ACTION);
  292.             return ( '\n' );
  293.             }
  294.  
  295. <SECT2>{OPTWS}/\n    {
  296.             bracelevel = 0;
  297.             continued_action = false;
  298.             BEGIN(ACTION);
  299.             return ( '\n' );
  300.             }
  301.  
  302. <SECT2>^{OPTWS}\n    ++linenum; return ( '\n' );
  303.  
  304. <SECT2>"<<EOF>>"    return ( EOF_OP );
  305.  
  306. <SECT2>^"%%".*        {
  307.             sectnum = 3;
  308.             BEGIN(SECT3);
  309.             return ( EOF ); /* to stop the parser */
  310.             }
  311.  
  312. <SECT2>"["([^\\\]\n]|{ESCSEQ})+"]"    {
  313.             int cclval;
  314.  
  315.             (void) strcpy( nmstr, (char *) yytext );
  316.  
  317.             /* check to see if we've already encountered this ccl */
  318.             if ( (cclval = ccllookup( (Char *) nmstr )) )
  319.                 {
  320.                 yylval = cclval;
  321.                 ++cclreuse;
  322.                 return ( PREVCCL );
  323.                 }
  324.             else
  325.                 {
  326.                 /* we fudge a bit.  We know that this ccl will
  327.                  * soon be numbered as lastccl + 1 by cclinit
  328.                  */
  329.                 cclinstal( (Char *) nmstr, lastccl + 1 );
  330.  
  331.                 /* push back everything but the leading bracket
  332.                  * so the ccl can be rescanned
  333.                  */
  334.                 PUT_BACK_STRING((Char *) nmstr, 1);
  335.  
  336.                 BEGIN(FIRSTCCL);
  337.                 return ( '[' );
  338.                 }
  339.             }
  340.  
  341. <SECT2>"{"{NAME}"}"    {
  342.             register Char *nmdefptr;
  343.             Char *ndlookup();
  344.  
  345.             (void) strcpy( nmstr, (char *) yytext );
  346.             nmstr[yyleng - 1] = '\0';  /* chop trailing brace */
  347.  
  348.             /* lookup from "nmstr + 1" to chop leading brace */
  349.             if ( ! (nmdefptr = ndlookup( nmstr + 1 )) )
  350.                 synerr( "undefined {name}" );
  351.  
  352.             else
  353.                 { /* push back name surrounded by ()'s */
  354.                 unput(')');
  355.                 PUT_BACK_STRING(nmdefptr, 0);
  356.                 unput('(');
  357.                 }
  358.             }
  359.  
  360. <SECT2>[/|*+?.()]    return ( (int) yytext[0] );
  361. <SECT2>.        RETURNCHAR;
  362. <SECT2>\n        ++linenum; return ( '\n' );
  363.  
  364.  
  365. <SC>","            return ( ',' );
  366. <SC>">"            BEGIN(SECT2); return ( '>' );
  367. <SC>">"/"^"        BEGIN(CARETISBOL); return ( '>' );
  368. <SC>{SCNAME}        RETURNNAME;
  369. <SC>.            synerr( "bad start condition name" );
  370.  
  371. <CARETISBOL>"^"        BEGIN(SECT2); return ( '^' );
  372.  
  373.  
  374. <QUOTE>[^"\n]        RETURNCHAR;
  375. <QUOTE>\"        BEGIN(SECT2); return ( '"' );
  376.  
  377. <QUOTE>\n        {
  378.             synerr( "missing quote" );
  379.             BEGIN(SECT2);
  380.             ++linenum;
  381.             return ( '"' );
  382.             }
  383.  
  384.  
  385. <FIRSTCCL>"^"/[^-\n]    BEGIN(CCL); return ( '^' );
  386. <FIRSTCCL>"^"/-        return ( '^' );
  387. <FIRSTCCL>-        BEGIN(CCL); yylval = '-'; return ( CHAR );
  388. <FIRSTCCL>.        BEGIN(CCL); RETURNCHAR;
  389.  
  390. <CCL>-/[^\]\n]        return ( '-' );
  391. <CCL>[^\]\n]        RETURNCHAR;
  392. <CCL>"]"        BEGIN(SECT2); return ( ']' );
  393.  
  394.  
  395. <NUM>[0-9]+        {
  396.             yylval = myctoi( yytext );
  397.             return ( NUMBER );
  398.             }
  399.  
  400. <NUM>","            return ( ',' );
  401. <NUM>"}"            BEGIN(SECT2); return ( '}' );
  402.  
  403. <NUM>.            {
  404.             synerr( "bad character inside {}'s" );
  405.             BEGIN(SECT2);
  406.             return ( '}' );
  407.             }
  408.  
  409. <NUM>\n            {
  410.             synerr( "missing }" );
  411.             BEGIN(SECT2);
  412.             ++linenum;
  413.             return ( '}' );
  414.             }
  415.  
  416.  
  417. <BRACEERROR>"}"        synerr( "bad name in {}'s" ); BEGIN(SECT2);
  418. <BRACEERROR>\n        synerr( "missing }" ); ++linenum; BEGIN(SECT2);
  419.  
  420.  
  421. <PERCENT_BRACE_ACTION,CODEBLOCK_2>{OPTWS}"%}".*        bracelevel = 0;
  422. <PERCENT_BRACE_ACTION,CODEBLOCK_2,ACTION>"reject"    {
  423.             ACTION_ECHO;
  424.             CHECK_REJECT(yytext);
  425.             }
  426. <PERCENT_BRACE_ACTION,CODEBLOCK_2,ACTION>"yymore"    {
  427.             ACTION_ECHO;
  428.             CHECK_YYMORE(yytext);
  429.             }
  430. <PERCENT_BRACE_ACTION,CODEBLOCK_2>{NAME}|{NOT_NAME}|.    ACTION_ECHO;
  431. <PERCENT_BRACE_ACTION,CODEBLOCK_2>\n            {
  432.             ++linenum;
  433.             ACTION_ECHO;
  434.             if ( bracelevel == 0 ||
  435.                  (doing_codeblock && indented_code) )
  436.                 {
  437.                 if ( ! doing_codeblock )
  438.                 fputs( "\tYY_BREAK\n", temp_action_file );
  439.                 
  440.                 doing_codeblock = false;
  441.                 BEGIN(SECT2);
  442.                 }
  443.             }
  444.  
  445.  
  446.     /* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */
  447. <ACTION>"{"        ACTION_ECHO; ++bracelevel;
  448. <ACTION>"}"        ACTION_ECHO; --bracelevel;
  449. <ACTION>[^a-z_{}"'/\n]+    ACTION_ECHO;
  450. <ACTION>{NAME}        ACTION_ECHO;
  451. <ACTION>"/*"        ACTION_ECHO; BEGIN(ACTION_COMMENT);
  452. <ACTION>"'"([^'\\\n]|\\.)*"'"    ACTION_ECHO; /* character constant */
  453. <ACTION>\"        ACTION_ECHO; BEGIN(ACTION_STRING);
  454. <ACTION>\n        {
  455.             ++linenum;
  456.             ACTION_ECHO;
  457.             if ( bracelevel == 0 )
  458.                 {
  459.                 fputs( "\tYY_BREAK\n", temp_action_file );
  460.                 BEGIN(SECT2);
  461.                 }
  462.             }
  463. <ACTION>.        ACTION_ECHO;
  464.  
  465. <ACTION_COMMENT>"*/"    ACTION_ECHO; BEGIN(ACTION);
  466. <ACTION_COMMENT>[^*\n]+    ACTION_ECHO;
  467. <ACTION_COMMENT>"*"    ACTION_ECHO;
  468. <ACTION_COMMENT>\n    ++linenum; ACTION_ECHO;
  469. <ACTION_COMMENT>.    ACTION_ECHO;
  470.  
  471. <ACTION_STRING>[^"\\\n]+    ACTION_ECHO;
  472. <ACTION_STRING>\\.    ACTION_ECHO;
  473. <ACTION_STRING>\n    ++linenum; ACTION_ECHO;
  474. <ACTION_STRING>\"    ACTION_ECHO; BEGIN(ACTION);
  475. <ACTION_STRING>.    ACTION_ECHO;
  476.  
  477. <ACTION,ACTION_COMMENT,ACTION_STRING><<EOF>>    {
  478.             synerr( "EOF encountered inside an action" );
  479.             yyterminate();
  480.             }
  481.  
  482.  
  483. <SECT2,QUOTE,CCL>{ESCSEQ}    {
  484.             yylval = myesc( yytext );
  485.             return ( CHAR );
  486.             }
  487.  
  488. <FIRSTCCL>{ESCSEQ}    {
  489.             yylval = myesc( yytext );
  490.             BEGIN(CCL);
  491.             return ( CHAR );
  492.             }
  493.  
  494.  
  495. <SECT3>.*(\n?)        ECHO;
  496. %%
  497.  
  498.  
  499. int yywrap()
  500.  
  501.     {
  502.     if ( --num_input_files > 0 )
  503.     {
  504.     set_input_file( *++input_files );
  505.     return ( 0 );
  506.     }
  507.  
  508.     else
  509.     return ( 1 );
  510.     }
  511.  
  512.  
  513. /* set_input_file - open the given file (if NULL, stdin) for scanning */
  514.  
  515. void set_input_file( file )
  516. char *file;
  517.  
  518.     {
  519.     if ( file )
  520.     {
  521.     infilename = file;
  522.     yyin = fopen( infilename, "r" );
  523.  
  524.     if ( yyin == NULL )
  525.         lerrsf( "can't open %s", file );
  526.     }
  527.  
  528.     else
  529.     {
  530.     yyin = stdin;
  531.     infilename = "<stdin>";
  532.     }
  533.     }
  534.